# coding: utf-8

'''
Um contador serve para contar ocorrências de itens.

Exemplo de uso::

    >>> c = Contador()
    >>> s = 'abbabaabbbaccaa'
    >>> for i in s: c.incluir(i)
    >>> c.contar('a')
    7
    >>> c.contar('c')
    2

Quando não existe o item acontece isso::

    >>> c.contar('x')
    Traceback (most recent call last):
      ...
    KeyError: 'x'
    
'''

class Contador(object):

    def __init__(self):
        self.dic = {}

    def incluir(self, item):
        qtd = self.dic.get(item, 0) + 1
        self.dic[item] = qtd

    def contar(self, item):
        return self.dic[item]

class ContadorTolerante(Contador):

    def contar(self, item):
        return self.dic.get(item, 0)


class ContadorTotalizador(Contador):
    '''
    Um ContadorTotalizador mantém um total de itens incluidos e
    pode informar a porcentagem de ocorrências de um item. Ex::

        >>> c = ContadorTotalizador()
        >>> s = 'aaabbb'
        >>> for i in s: c.incluir(i)
        >>> c.contar('a')
        3
        >>> c.porcentagem('a')
        '50.0%'
    '''

    total = 0
            
    def incluir(self, item):    
        super(ContadorTotalizador,self).incluir(item)
        self.total += 1
        
    def porcentagem(self, item):
        pct = float(self.contar(item)) / self.total * 100
        return '%0.1f%%' % pct
        
    def incluir_varios(self, iteravel):
        for i in iteravel:
            self.incluir(i)
            
class ContadorTotalizadorTolerante(ContadorTolerante, ContadorTotalizador):
    '''
    Um ContadorTotalizadorTolerante combina métodos de dois contadores. Ex::

        >>> c = ContadorTotalizadorTolerante()
        >>> s = 'aaabbb'
        >>> for i in s: c.incluir(i)
        >>> c.contar('a')
        3
        >>> c.porcentagem('a')
        '50.0%'
        >>> c.porcentagem('x')
        '0.0%'
        >>> for cls in ContadorTotalizadorTolerante.__mro__: print cls.__name__
        ContadorTotalizadorTolerante
        ContadorTolerante
        ContadorTotalizador
        Contador
        object


    '''
             
        
if __name__=='__main__':
    import doctest
    doctest.testmod()
